
/*
 * UPProject.java
 *
 * Created on 2010-11-25, 22:37:51
 */

package JET.UtilPanels;

import JET.Centers.ControlCenter;
import JET.Centers.ControlCenterHelper;
import JET.Centers.Graphics.GUICenter;
import JET.Centers.Scripts.MyScript;
import JET.Constants;
import JET.Frames.DataModels.DataModelsFactory;
import JET.Frames.ScenePropDialog;
import JET.ImageUtils.ImageUtils;
import JET.Scene;
import JET.Scene.ScriptsTreeNode;
import JET.mygui.UtilTabsPane.UtilTabsPaneTab;
import JET.physics.interfaces.ProjectTreeNode;
import JET.physics.interfaces.ProjectTreeSceneFilterNode;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.EnumMap;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

/**
 *
 * @author 057Ry
 */
public class UPProject extends javax.swing.JPanel implements UtilTabsPaneTab, Constants {

    private ControlCenter CC = ControlCenter.getInstance();
    
    /** Creates new form UPProject */
    public UPProject() {
        initComponents();
    }

    public GUICenter.UtilTabs getId() {
        return GUICenter.UtilTabs.Project;
    }

    public boolean isScrollable() {
        return true;
    }

    public ProjectTree getProjectTree() {
        return (ProjectTree) projectTree;
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        sceneFilterPopupMenu = new javax.swing.JPopupMenu();
        newFilterMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        newSceneMenuItem = new javax.swing.JMenuItem();
        sceneNodePopupMenu = new javax.swing.JPopupMenu();
        openSceneTabMenuItem = new javax.swing.JMenuItem();
        closeSceneTabMenuItem = new javax.swing.JMenuItem();
        deleteSceneMenuItem = new javax.swing.JMenuItem();
        propsMenuItem = new javax.swing.JMenuItem();
        sceneSriptsPopupMenu = new javax.swing.JPopupMenu();
        newScriptMenuItem = new javax.swing.JMenuItem();
        myScriptPopupMenu = new javax.swing.JPopupMenu();
        openMyScriptTabMenuItem = new javax.swing.JMenuItem();
        closeMyScriptTabMenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        deleteScriptMenuItem = new javax.swing.JMenuItem();
        jScrollPane1 = new javax.swing.JScrollPane();
        projectTree = new ProjectTree();

        newFilterMenuItem.setText("New Filter");
        newFilterMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newFilterMenuItemActionPerformed(evt);
            }
        });
        sceneFilterPopupMenu.add(newFilterMenuItem);
        sceneFilterPopupMenu.add(jSeparator1);

        newSceneMenuItem.setText("New scene");
        newSceneMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newSceneMenuItemActionPerformed(evt);
            }
        });
        sceneFilterPopupMenu.add(newSceneMenuItem);

        openSceneTabMenuItem.setText("Open");
        openSceneTabMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openSceneTabMenuItemActionPerformed(evt);
            }
        });
        sceneNodePopupMenu.add(openSceneTabMenuItem);

        closeSceneTabMenuItem.setText("Close");
        closeSceneTabMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeSceneTabMenuItemActionPerformed(evt);
            }
        });
        sceneNodePopupMenu.add(closeSceneTabMenuItem);

        deleteSceneMenuItem.setText("delete");
        deleteSceneMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteSceneMenuItemActionPerformed(evt);
            }
        });
        sceneNodePopupMenu.add(deleteSceneMenuItem);

        propsMenuItem.setText("Properties");
        propsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                propsMenuItemActionPerformed(evt);
            }
        });
        sceneNodePopupMenu.add(propsMenuItem);

        newScriptMenuItem.setText("New script");
        newScriptMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newScriptMenuItemActionPerformed(evt);
            }
        });
        sceneSriptsPopupMenu.add(newScriptMenuItem);

        openMyScriptTabMenuItem.setText("Open");
        openMyScriptTabMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openMyScriptTabMenuItemActionPerformed(evt);
            }
        });
        myScriptPopupMenu.add(openMyScriptTabMenuItem);

        closeMyScriptTabMenuItem.setText("Close");
        closeMyScriptTabMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeMyScriptTabMenuItemActionPerformed(evt);
            }
        });
        myScriptPopupMenu.add(closeMyScriptTabMenuItem);
        myScriptPopupMenu.add(jSeparator2);

        deleteScriptMenuItem.setText("delete");
        deleteScriptMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteScriptMenuItemActionPerformed(evt);
            }
        });
        myScriptPopupMenu.add(deleteScriptMenuItem);

        projectTree.setModel(DataModelsFactory.getProjectTreeModel());
        projectTree.setEditable(true);
        jScrollPane1.setViewportView(projectTree);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE)
        );

        getAccessibleContext().setAccessibleName("Project");
    }// </editor-fold>//GEN-END:initComponents

    private void newFilterMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newFilterMenuItemActionPerformed
        if (projectTreeNode!=null) {
            ProjectTreeSceneFilterNode ptsfn = new ProjectTreeSceneFilterNode();
            ProjectTreeSceneFilterNode projectNode = (ProjectTreeSceneFilterNode) projectTreeNode;
            projectNode.addFilterNode(ptsfn);
            DataModelsFactory.getProjectTreeModel().fireWholeTreeChanged();
        }
    }//GEN-LAST:event_newFilterMenuItemActionPerformed

    private void newSceneMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newSceneMenuItemActionPerformed
        Scene scene = new Scene();
        scene.getJETContext().setMainBound(SCENE_START_WIDTH, SCENE_START_HEIGHT);
        CC.addScene(scene, scene.getName());
        
        ProjectTreeSceneFilterNode filterNode = (ProjectTreeSceneFilterNode) projectTreeNode;
        filterNode.addScene(scene);
        DataModelsFactory.getProjectTreeModel().fireScenesTreeChanged();
    }//GEN-LAST:event_newSceneMenuItemActionPerformed

    private void closeSceneTabMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeSceneTabMenuItemActionPerformed
        Scene scene = (Scene) projectTreeNode;
        CC.GUIC.closeSceneTab(scene.getName());
    }//GEN-LAST:event_closeSceneTabMenuItemActionPerformed

    private void newScriptMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newScriptMenuItemActionPerformed
        Scene scene = (Scene) projectTreeNode;
        String name = "script"+ scene.SC.getScriptsCount() +".js";
        MyScript script = new MyScript(name);
        scene.SC.addScript(script);
        DataModelsFactory.getProjectTreeModel().fireScenesTreeChanged();
    }//GEN-LAST:event_newScriptMenuItemActionPerformed

    private void closeMyScriptTabMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeMyScriptTabMenuItemActionPerformed
        MyScript myScript = (MyScript) projectTreeNode;
        CC.GUIC.closeScriptTab(myScript);
    }//GEN-LAST:event_closeMyScriptTabMenuItemActionPerformed

    private void openSceneTabMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openSceneTabMenuItemActionPerformed
        Scene scene = (Scene) projectTreeNode;
        CC.GUIC.openSceneTab((scene).getName());
        CC.GUIC.setCurrentScene((scene).getName());
        DataModelsFactory.getProjectTreeModel().fireWholeTreeChanged();
    }//GEN-LAST:event_openSceneTabMenuItemActionPerformed

    private void openMyScriptTabMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMyScriptTabMenuItemActionPerformed
        MyScript myScript = (MyScript) projectTreeNode;
        CC.GUIC.openScriptTab(myScript);
    }//GEN-LAST:event_openMyScriptTabMenuItemActionPerformed

    private void deleteScriptMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteScriptMenuItemActionPerformed
        MyScript myScript = (MyScript) projectTreeNode;
        CC.GUIC.closeScriptTab(myScript);
        Scene scene = ControlCenterHelper.getSceneOwningScript(myScript);
        if (scene!=null) {
            scene.SC.removeScript(myScript);
            DataModelsFactory.getProjectTreeModel().fireScenesTreeChanged();
        }
    }//GEN-LAST:event_deleteScriptMenuItemActionPerformed

    private void deleteSceneMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSceneMenuItemActionPerformed
        Scene scene = (Scene) projectTreeNode;
        CC.GUIC.closeSceneTab(scene.getName());
        CC.GUIC.removeSceneTab(scene.getName());
        CC.removeScene(scene.getName());

        Collection<MyScript> scCol = scene.SC.getScriptsSync();
        synchronized(scCol) {
            for(MyScript s : scCol)
            CC.GUIC.closeScriptTab(s);
        }
        
        DataModelsFactory.getProjectTreeModel().fireScenesTreeChanged();
    }//GEN-LAST:event_deleteSceneMenuItemActionPerformed

    private void propsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_propsMenuItemActionPerformed
        Scene scene = (Scene) projectTreeNode;
        ScenePropDialog spd = new ScenePropDialog(scene, CC.GUIC.getRootFrame(), true);
        spd.setLocationRelativeTo(CC.GUIC.getRootFrame());
        spd.setVisible(true);
    }//GEN-LAST:event_propsMenuItemActionPerformed

    public class ProjectTree extends JTree {
        public ProjectTree() {
            super();
            this.setDragEnabled(true);
            this.setCellRenderer(new ProjectTreeCellRenderer());

            this.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {

                    int selRow = ProjectTree.this.getRowForLocation(e.getX(), e.getY());
                    TreePath selPath = ProjectTree.this.getPathForLocation(e.getX(), e.getY());
                    if(selRow != -1) {
                        if(e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON3) {
                            Object lastPathComp = selPath.getLastPathComponent();
                            if (lastPathComp instanceof ProjectTreeSceneFilterNode) {
                                sceneFilterPopupMenu.show(projectTree, e.getX(), e.getY());
                                projectTreeNode = (ProjectTreeNode) lastPathComp;
                            }
                            else if (lastPathComp instanceof Scene) {
                                sceneNodePopupMenu.show(projectTree, e.getX(), e.getY());
                                projectTreeNode = (ProjectTreeNode) lastPathComp;
                            }
                            else if (lastPathComp instanceof Scene.ScriptsTreeNode) {
                                sceneSriptsPopupMenu.show(projectTree, e.getX(), e.getY());
                                projectTreeNode = (Scene) selPath.getPathComponent(selPath.getPathCount()-2);
                            }
                            else if (lastPathComp instanceof MyScript) {
                                myScriptPopupMenu.show(projectTree, e.getX(), e.getY());
                                projectTreeNode =  (MyScript) selPath.getPathComponent(selPath.getPathCount()-1);
                            }
                        }
                        else if(e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
                            Object lastPathComp = selPath.getLastPathComponent();
                            if (lastPathComp instanceof Scene) {
                                CC.GUIC.openSceneTab(((Scene) lastPathComp).getName());
                                CC.GUIC.setCurrentScene(((Scene) lastPathComp).getName());
                                DataModelsFactory.getProjectTreeModel().fireWholeTreeChanged();
                            }
                            else if (lastPathComp instanceof MyScript) {
                                CC.GUIC.openScriptTab((MyScript) lastPathComp);
                            }
                        }
                    }
                }
            });
        }
    }

    ProjectTreeNode projectTreeNode;

    public enum ProjectTreeNodeType {
        SceneFilter,
        Scene,
        SceneScripts,
        Script
    }

    public class ProjectTreeCellRenderer extends JLabel implements TreeCellRenderer {

        private HashMap<ProjectTreeNodeType, ImageIcon> icons;
        ImageIcon dot = null;
        Color bgColor = Color.WHITE;
        Color bgSelectedColor = new Color(49, 106, 197);

        boolean selected;

        public ProjectTreeCellRenderer() {
            loadIcons();
        }

        private void loadIcons() {
            dot = ImageUtils.loadImageIconFromResources("/JET/Images/sceneTreeIcons/dot15x15.png");
            
            icons = new HashMap<ProjectTreeNodeType, ImageIcon>();
            icons.put(ProjectTreeNodeType.SceneFilter, ImageUtils.loadImageIconFromResources("/JET/mygui/images/tab_icon_folder.png"));
            icons.put(ProjectTreeNodeType.Scene, ImageUtils.loadImageIconFromResources("/JET/Images/sceneTreeIcons/scene.png"));
            icons.put(ProjectTreeNodeType.SceneScripts, ImageUtils.loadImageIconFromResources("/JET/mygui/images/tab_icon_folder.png"));
            icons.put(ProjectTreeNodeType.Script, ImageUtils.loadImageIconFromResources("/JET/mygui/images/tab_icon_js.png"));
        }

        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            if (selected) bgColor = bgSelectedColor;
            else          bgColor = Color.WHITE;

            this.setText(value.toString());

            if (value instanceof Scene) setIcon(icons.get(ProjectTreeNodeType.Scene));
            else if (value instanceof ProjectTreeSceneFilterNode) setIcon(icons.get(ProjectTreeNodeType.SceneFilter));
            else if (value instanceof Scene.ScriptsTreeNode) setIcon(icons.get(ProjectTreeNodeType.SceneScripts));
            else if (value instanceof MyScript) setIcon(icons.get(ProjectTreeNodeType.Script));
            else
                setIcon(dot);

            this.selected = selected;

            return this;
        }

        public void paint(Graphics g) {
            g.setColor(bgColor);
            g.fillRect(0, 0, getWidth(), getHeight());
            //TODO : paint node text in white color
            
            if (selected)
                this.setForeground(Color.WHITE);
            else
                this.setForeground(Color.BLACK);

            super.paint(g);
        }

        public Dimension getPreferedSize() {
            Dimension size = super.getPreferredSize();
            return new Dimension((int)size.getWidth(), (int)size.getHeight()+5);
        }

        @Override
        public Dimension getSize() {
            Dimension size = super.getSize();
            return new Dimension((int)size.getWidth(), (int)size.getHeight()+5);
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem closeMyScriptTabMenuItem;
    private javax.swing.JMenuItem closeSceneTabMenuItem;
    private javax.swing.JMenuItem deleteSceneMenuItem;
    private javax.swing.JMenuItem deleteScriptMenuItem;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu myScriptPopupMenu;
    private javax.swing.JMenuItem newFilterMenuItem;
    private javax.swing.JMenuItem newSceneMenuItem;
    private javax.swing.JMenuItem newScriptMenuItem;
    private javax.swing.JMenuItem openMyScriptTabMenuItem;
    private javax.swing.JMenuItem openSceneTabMenuItem;
    private javax.swing.JTree projectTree;
    private javax.swing.JMenuItem propsMenuItem;
    private javax.swing.JPopupMenu sceneFilterPopupMenu;
    private javax.swing.JPopupMenu sceneNodePopupMenu;
    private javax.swing.JPopupMenu sceneSriptsPopupMenu;
    // End of variables declaration//GEN-END:variables

}
